<?php

class PHPImageBuilder
{
	const GD = 'GD library';
	
	const IMAGEMAGICK = 'Imagemagick';
	
	const LANDSCAPE = 'Landscape';
	const PORTRAIT = 'Portrait';
	const SQUARE = 'Square';
	
	const JPG = 'jpg';
	const PNG = 'png';
	const GIF = 'gif';
	
	public $arrError = array();
	
	private $_engine = false;
	private $_arrNewFormats = array();
	private $_outputextension = JPG;
	private $_outputpath = false;
	private $_source = false;
	private $_sourcetype = false;
	private $_sourceorientation = false;
	private $_sourcename = 'resize';
	private $_files = array();
	
	public function __construct($engine = GD)
	{
		$this->_engine = $engine;
		
		$this->checkEngine();//check if there is a image library installed 
	}

	public function getFiles()
	{
		return $this->_files;
	}
	
	public function setSource($source)
	{
		if(file_exists($source))
		{
			 if(function_exists('getimagesize'))
			 {
			 	$arrImageInfo = getimagesize($source);
			 	
			 	$this->_sourceorientation = $this->getOrientation($arrImageInfo);
			 	
			 	switch($arrImageInfo['mime'])
			 	{
			 		case 'image/jpeg':
			 			$this->_sourcetype = JPG;
			 			$this->_source = $source;
			 			return true;
			 		break;
			 		case 'image/gif':
			 			$this->_sourcetype = GIF;
			 			$this->_source = $source;
			 			return true;
			 		break;
			 		case 'image/png':
			 			$this->_sourcetype = PNG;
			 			$this->_source = $source;
			 			return true;
			 		break;	
			 		default:
			 			$this->arrError[2] = 'Image type not supported';
						return false;
			 		break;
			 	}
			 }
			 else
			 {
			 	throw new Exception('Function getimagesize is not installed');
			 }
		}
		else
		{
			$this->arrError[1] = 'Image not found';
			return false;
		}
	}
	
	public function setOutputPath($targetpath)
	{
		if(file_exists($targetpath)){
			if(is_writable($targetpath)){
				if(substr($targetpath, -1) == '/'){
					$this->_outputpath = $targetpath;
				}else
				{
					$this->_outputpath = $targetpath.'/';
				}
			}
			else
			{
				throw new Exception('Outputpath is not writable');
			}
		}
		else 
		{
			throw new Exception('Outputpath not found');
		}
	}
	
	public function setName($name)
	{
		$this->_sourcename = $this->_sourcename.'-'.$name;
	}
	
	public function setOutputExtension($extension)
	{
		switch($extension)
		{
			case 'jpg':
				$this->_outputextension = JPG;
			break;
			case 'gif':
				$this->_outputextension = GIF;
			break;
			case 'png':
				$this->_outputextension = PNG;
			break;
			default:
				throw new Exception('no right format selected');
			break;
		}
	}
	
	public function setFormat($format)
	{
		if(is_array($format))
		{
			foreach($format as $for)
			{
				$arr = explode('x',$for);
				$this->_arrNewFormats[] = array('width'=>$arr[0], 'height'=>$arr[1]);
			}
		}
		else
		{
			if(is_string($format))
			{
				$arr = explode('x',$format);
				$this->_arrNewFormats[] = array('width'=>$arr[0], 'height'=>$arr[1]);
			}
			else
			{
				throw new ErrorException('Incorrect format');
			}
		}
	}
	
	public function generate()
	{
		if($this->checkAllPrequestions())
		{
			return $this->build();
		}
		else 
		{
			return false;
		}
	}
	
	
	/*
	 * Private functions
	 */
	
	private function build()
	{
		$info =  getimagesize($this->_source);
		
		$currentHeight = $info[1];
		$currentWidth = $info[0];
		

		foreach($this->_arrNewFormats as $format)
		{
			switch($this->_sourceorientation)
			{
				case LANDSCAPE:

					$newWidth = $format['width'];
					$ratio = $format['width']/$currentWidth;

					$newHeight = $currentWidth*$ratio;
	
					
					if($newHeight < $format['height'])
					{
						$newHeight = $format['height'];
						$ratio = $format['height']/$currentHeight;

						$newWidth = $currentHeight*$ratio;

					}
					
					$dst_x = 0;
					$dst_y = 0;
					$src_x = 0;
					$src_y = 0;
					$dst_w = $newWidth;
					$dst_h = $newHeight;
					$src_w = $currentWidth;
					$src_h = $currentHeight;
					$pct = 100;

				break;
				case PORTRAIT:
					$newWidth = $format['width'];
					$ratio = $format['width']/$currentWidth;

					$newHeight = $currentWidth*$ratio;
	
					
					if($newHeight < $format['height'])
					{
						print_r($format);
						$newHeight = $format['height'];
						$ratio = $format['height']/$currentHeight;

						$newWidth = $currentHeight*$ratio;
					}
					
					$dst_x = 0;
					$dst_y = 0;
					$src_x = 0;
					$src_y = 0;
					$dst_w = $newWidth;
					$dst_h = $newHeight;
					$src_w = $currentWidth;
					$src_h = $currentHeight;
					$pct = 100;

				break;
				case SQUARE:
					$newWidth = $format['width'];
					$ratio = $format['width']/$currentWidth;

					$newHeight = $currentWidth*$ratio;
	
					if($newHeight < $format['height'])
					{
						print_r($format);
						$newHeight = $format['height'];
						$ratio = $format['height']/$currentHeight;

						$newWidth = $currentHeight*$ratio;
					}
					
					$dst_x = 0;
					$dst_y = 0;
					$src_x = 0;
					$src_y = 0;
					$dst_w = $newWidth;
					$dst_h = $newHeight;
					$src_w = $currentWidth;
					$src_h = $currentHeight;
					$pct = 100;

				break;
			}
			
			/*
			 * must be replaced for other resize engine
			 */

			$src_image = imagecreatefromjpeg($this->_source);
			
			$im = imagecreatetruecolor($format['width'], $format['height']);
			
			imagecopyresampled($im, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
			//imagecopymerge($im, $src_image, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct);
			
			switch($this->_outputextension)
			{
				case JPG:
					imagejpeg($im, $this->buildSavePath($format['width'], $format['height']),'85');
				break;
				case PNG:
					imagepng($im, $this->buildSavePath($format['width'],  $format['height']));
				break;
				case GIF:
					imagegif($im, $this->buildSavePath($format['width'],  $format['height']));
				break;
			}
			
			$this->_files[] =$this->buildSavePath($format['width'],  $format['height']);

			/*
			 * Unitil here
			 */
			/*new code 
			switch($this->_engine)
			{
				case IMAGEMAGICK:
					//@todo Build the image magick resizer
				break;
				case GD:
					
				break;
			}
			
			$this->_files[] =$this->buildSavePath($format['width'],  $format['height']);*/
		}
		return $this->_files;
	}
	
	private function buildSavePath($width, $height)
	{
		return $this->_outputpath.$this->_sourcename.'-'.$width.'x'.$height.'.'.strtolower($this->_outputextension);
	}
	
	private function checkAllPrequestions()
	{
		if(!isset($this->_engine))
		{
			$this->arrError[3] = 'No engine selected';
		}
		
		if(count($this->_arrNewFormats) == 0)
		{
			$this->arrError[4] = 'No format selected';
		}
		
		if($this->_outputextension == false)
		{
			$this->arrError[5] = 'No output extension selected';
		}
		
		if(!isset($this->_outputpath))
		{
			$this->arrError[6] = 'No outputpath set';
		}
		
		if(!isset($this->_source))
		{
			$this->arrError[7] = 'No source set';
		}
		
		if(count($this->arrError) > 0)
		{
			return false;	
		}
		else 
		{
			return true;
		}	
	}
	
	private function getOrientation($imageinfo)
	{
		$currentHeight = $imageinfo[1];
		$currentWidth = $imageinfo[0];
		
		if($currentHeight<$currentWidth)
		{
			$return = LANDSCAPE;
		}
		else
		{
			$return = PORTRAIT;
		}
	
		if($currentHeight == $currentWidth)
		{
			$return = SQUARE;
		}
		
		return $return;
	}
	
	private function checkEngine()
	{
		switch($this->_engine)
		{
			case GD:
				if(!is_array(gd_info()))
				{
					throw new Exception('No GD library installed');
				}
			break;
			default:
				throw new Exception('No image library installed');
			break;
		}
	}
}